package com.apes.scm.rbac.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.rop.converter.DateUtils;
import com.apes.framework.util.EventUtil;
import com.apes.hr.base.repository.WorkPostRepository;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.frame.model.BranchEntry;
import com.apes.scm.masterdata.frame.repository.BranchRepository;
import com.apes.scm.masterdata.party.model.Corporate;
import com.apes.scm.masterdata.party.model.Party;
import com.apes.scm.masterdata.party.repository.CorporateRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.rbac.model.LocalPermit;
import com.apes.scm.rbac.model.LocalPermitItem;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.model.Role;
import com.apes.scm.rbac.repository.LocalPermitRepository;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.RoleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.util.*;


@Service("localPermitService")
public class LocalPermitService extends DomainService {

    @Autowired
    private LocalPermitRepository localPermitRepository;
    @Autowired
    private CorporateRepository corporateRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private BranchRepository branchRepository;
    @Autowired
    private WorkPostRepository workPostRepository;
    @Autowired
    private PostRepository postRepository;

    /*
     * 本地权限保存/更新
     * */
    public LocalPermit save(SimpleRequest simpleRequest) {
        LocalPermit localPermit = simpleRequest.getO(LocalPermit.class);
        convertPurposeMapToLocalPermitItems(localPermit);
        LocalPermit result = localPermitRepository.saveAndFlush(localPermit);
        // 得重新把前端需要的对象重新赋值
        result.setPermitPurposeBelong(localPermit.getPermitPurposeBelong());
        result.setPermitPurposeOperate(localPermit.getPermitPurposeOperate());
        result.setPermitPurposeSearch(localPermit.getPermitPurposeSearch());
        return result;
    }


    /*
     * 本地权限删除功能
     * */
    public String delete(SimpleRequest simpleRequest) {
        String id = simpleRequest.get("id");
        LocalPermit localPermit = localPermitRepository.findOne(id);
        localPermitRepository.delete(localPermit);
        return "删除成功！";
    }


    /*
     * 权限Map 转换成 LocalPermitItem
     * */
    private void convertPurposeMapToLocalPermitItems(LocalPermit localPermit) {
        Set<LocalPermitItem> localPermitItemSet = new HashSet<>();
        // 依次转换写入  localPermitItemSet
        mapperPermitPurposeBelong(localPermitItemSet, localPermit.getPermitPurposeBelong(), "pp_belong");
        mapperPermitItems(localPermitItemSet, localPermit.getPermitPurposeOperate(), "pp_operate");
        mapperPermitItems(localPermitItemSet, localPermit.getPermitPurposeSearch(), "pp_search");

        localPermit.setLocalPermitItems(localPermitItemSet);
    }

    /*
     * LocalPermitItem 转换成权限Map
     * */
    private void convertLocalPermitItemsToPurposeMap(LocalPermit localPermit) {
        Optional.ofNullable(localPermit).ifPresent(
                (loP) -> {
                    localPermit.setPermitPurposeBelong(getPermitPurposeBelong(localPermit.getLocalPermitItems(), "pp_belong"));
                    localPermit.setPermitPurposeOperate(getPermitPurposeMap(localPermit.getLocalPermitItems(), "pp_operate"));
                    localPermit.setPermitPurposeSearch(getPermitPurposeMap(localPermit.getLocalPermitItems(), "pp_search"));
                }
        );

    }


    /*
     * 转换规则
     * */
    private void mapperPermitItems(Set<LocalPermitItem> localPermitItemSet, JSONObject purposeObject, String purposeId) {
        Enumeration purpose = new Enumeration();
        purpose.setId(purposeId);
        purposeObject.forEach(
                (k, v) -> {
                    Enumeration type = new Enumeration();
                    type.setId(k);
                    ((List<JSONObject>) v).stream().forEach(
                            (item) -> {
                                LocalPermitItem localPermitItem = new LocalPermitItem();
                                localPermitItem.setPurpose(purpose);
                                localPermitItem.setType(type);
                                localPermitItem.setOrgId(item.getString("id"));
                                localPermitItem.setOrgName(item.getString("name"));
                                localPermitItemSet.add(localPermitItem);
                            }
                    );
                }
        );
    }

    /**
     * 所属权限转换规则
     *
     * @param localPermitItemSet
     * @param purposeObject
     * @param purposeId
     */
    private void mapperPermitPurposeBelong(Set<LocalPermitItem> localPermitItemSet, JSONObject purposeObject, String purposeId) {
        Enumeration purpose = new Enumeration();
        purpose.setId(purposeId);
        purposeObject.forEach(
                (k, v) -> {
                    Enumeration type = new Enumeration();
                    type.setId(k);
                    JSONObject permitPurposeBelong = (JSONObject) v;
                    LocalPermitItem localPermitItem = new LocalPermitItem();
                    localPermitItem.setPurpose(purpose);
                    localPermitItem.setType(type);
                    localPermitItem.setOrgId(permitPurposeBelong.getString("id"));
                    localPermitItem.setOrgName(permitPurposeBelong.getString("name"));
                    localPermitItemSet.add(localPermitItem);

                }
        );
    }


    /*
     * 本地权限界面弹窗分页查询
     * */
    public Page<LocalPermit> findAllForUi(SimpleRequest simpleRequest) {
        Page<LocalPermit> localPermitPage = simpleRequest.getO(Page.class);
        // 转化格式 转换成Map
        localPermitPage.getContent().forEach(this::convertLocalPermitItemsToPurposeMap);
        return localPermitPage;
    }


    /*
     * 本地权限界面ID回车查询
     * */
    public LocalPermit findOneForUi(SimpleRequest simpleRequest) {
        LocalPermit localPermit = localPermitRepository.findOne((String) simpleRequest.get("id"));
        // 格式转换
        convertLocalPermitItemsToPurposeMap(localPermit);
        return localPermit;
    }


    /*
     * 获取对应权限（操作、查询）前端需要的格式
     * */
    private JSONObject getPermitPurposeMap(Set<LocalPermitItem> localPermitItems, String purpose) {
        if (localPermitItems == null) return null;
        JSONObject permitPurposeMap = new JSONObject();
        List<Map> company = new ArrayList<>();
        List<Map> dept = new ArrayList<>();
        List<Map> location = new ArrayList<>();
        List<Map> site = new ArrayList<>();
        List<Map> supplier = new ArrayList<>();

        localPermitItems.stream()
                .filter(item -> item.getPurpose().getId().equals(purpose))
                .forEach(item -> {
                    Map result = new HashMap();
                    result.put("id", item.getOrgId());
                    result.put("name", item.getOrgName());
                    if (item.getType().getId().equals("pt_company")) {  // 公司
                        Party party = partyRoleRepository.findOne(item.getOrgId()).getParty();
                        result.put("operation", Optional.ofNullable(corporateRepository.findByParty(party).getOperation()).orElse(new Enumeration()).getDescription());
                        company.add(result);
                    } else if (item.getType().getId().equals("pt_dept")) {  // 部门
                        dept.add(result);
                    } else if (item.getType().getId().equals("pt_location")) { // 仓库
                        location.add(result);
                    } else if (item.getType().getId().equals("pt_site")) { // 物流站点
                        site.add(result);
                    } else if (item.getType().getId().equals("pt_supplier")) { // 供应商
                        supplier.add(result);
                    }
                });
        permitPurposeMap.put("pt_company", company);
        permitPurposeMap.put("pt_dept", dept);
        permitPurposeMap.put("pt_location", location);
        permitPurposeMap.put("pt_site", site);
        permitPurposeMap.put("pt_supplier", site);
        return permitPurposeMap;
    }

    /**
     * 获取对应权限（所属）前端需要的格式
     *
     * @param localPermitItems
     * @param purpose
     * @return
     */
    private JSONObject getPermitPurposeBelong(Set<LocalPermitItem> localPermitItems, String purpose) {
        if (localPermitItems == null) return null;
        JSONObject permitPurposeMap = new JSONObject();
        localPermitItems.stream().filter(
                (LocalPermitItem item) -> item.getPurpose().getId().equals(purpose)
        ).forEach(
                (LocalPermitItem item) -> {
                    Map result = new HashMap();
                    result.put("id", item.getOrgId());
                    result.put("name", item.getOrgName());
                    if (item.getType().getId().equals("pt_company")) {  // 公司
                        Party party = partyRoleRepository.findOne(item.getOrgId()).getParty();
                        Corporate corporate = corporateRepository.findByParty(party);
                        if (corporate != null) {
                            result.put("operation", Optional.ofNullable(corporate.getOperation()).orElse(new Enumeration()).getDescription());
                        } else {
                            result.put("operation", null);
                        }
                        permitPurposeMap.put("pt_company", result);
                    } else if (item.getType().getId().equals("pt_dept")) {  // 部门
                        permitPurposeMap.put("pt_dept", result);
                    } else if (item.getType().getId().equals("pt_location")) { // 仓库
                        permitPurposeMap.put("pt_location", result);
                    } else if (item.getType().getId().equals("pt_site")) { // 物流站点
                        permitPurposeMap.put("pt_site", result);
                    } else if (item.getType().getId().equals("pt_supplier")) {// 供应商
                        permitPurposeMap.put("pt_supplier", result);
                    }
                }
        );
        return permitPurposeMap;
    }

    /**
     * 生成 本地权限 和 同步到旧框架
     *
     * @param request
     * @return
     */
    @Listener(topic = "event:cm.branchEntry.setLocalPermit")
    public void setLocalPermit(SimpleRequest request) {
        BranchEntry branchEntry = (BranchEntry) request.getData();

        LocalPermit localPermitL = new LocalPermit(); // 仓库
        localPermitL.setId(branchEntry.getCompany().getId() + branchEntry.getDeptId());
        localPermitL.setName(branchEntry.getName());
        localPermitL = setPermitPurpose(localPermitL, branchEntry);
        convertPurposeMapToLocalPermitItems(localPermitL);
        LocalPermit branchLocal = localPermitRepository.saveAndFlush(localPermitL);
//        synBDQX(branchLocal,"02");
        setPost(localPermitL, branchEntry);
    }

    public void synBDQX(SimpleRequest request) {
        JSONObject queryBDQX = new JSONObject();
        queryBDQX.put("BDQXID", "100200000");
        queryBDQX.put("qrylx", "AUT_BDQX");
        String queryBDQXTopic = "event:cm.branchEntry.queryBDQX";
        EventUtil.sendSynEvent(this, queryBDQXTopic, queryBDQX).stream().findFirst().get();
    }

    public void synBDQX2(LocalPermit localPermit, String QXFWID) {

        localPermit.getLocalPermitItems();
        JSONObject synBDQX = new JSONObject();
        synBDQX.put("BDQXID", localPermit.getId());
        synBDQX.put("BDQXMC", localPermit.getName());
        synBDQX.put("QXFWID", QXFWID);
        synBDQX.put("DBCN", "ERP");
        synBDQX.put("TS01", DateUtils.format(localPermit.getLastUpdatedStamp(), "yyyyMMdd.HHmmss.SSS"));
        synBDQX.put("LRR", "admin");
        synBDQX.put("LRRQ_SJ", DateUtils.format(localPermit.getCreateDate(), "yyyy-MM-dd HH:mm:ss"));
        String topic = "event:cm.branchEntry.synBDQX";
        Boolean flg = (Boolean) EventUtil.sendSynEvent(this, topic, synBDQX).stream().findFirst().get();
        if (!flg) {
            throw new RuntimeException("同步本地权限到旧框架时报错!");
        }
        JSONObject synBDQXMX = new JSONObject();
        synBDQXMX.put("BDQXID", localPermit.getId());
        synBDQXMX.put("QXWDID", "MDID");

        String BDQXMXtopic = "event:cm.branchEntry.synBDQXMX";
        Boolean BDQXMXflg = (Boolean) EventUtil.sendSynEvent(this, BDQXMXtopic, synBDQXMX).stream().findFirst().get();
        if (!BDQXMXflg) {
            throw new RuntimeException("同步本地权限明细到旧框架时报错!");
        }
    }

    /**
     * 生成 本地角色 和 同步到旧框架
     *
     * @param
     * @return
     */
    public void setPost(LocalPermit localPermit, BranchEntry branchEntry) {
        List<String> list = new ArrayList<String>(Arrays.asList("FM01", "FM02", "FM04", "FM05", "FM06", "FM07", "FM12"));
        list.forEach(s -> {
            Role role = roleRepository.findOne(s);
            if (role == null) throw new RuntimeException("通用角色" + s + "没有设置。");
            Set<Role> roles = new HashSet<>();
            roles.add(role);
            Post post = new Post();
            //  F+通用角色编码+门店的本地权限编码
            post.setId(s + localPermit.getId());
            post.setName(localPermit.getName() + role.getName());
            post.setOrigin(s + localPermit.getId());
            post.setCompany(branchEntry.getCompany());
            post.setBranch(branchRepository.findOne(branchEntry.getBranchId()));
            post.setWorkPost(workPostRepository.findByName(role.getName()));
            switch (role.getName()) {
                case "美容技师": {
                    post.setWorkPost(workPostRepository.findByName("美容组"));
                    break;
                }
                case "机电技师": {
                    post.setWorkPost(workPostRepository.findByName("机电组"));
                    break;
                }
                case "店长（赋能门店）": {
                    post.setWorkPost(workPostRepository.findByName("店长"));
                    break;
                }
                case "店长助理（赋能门店）": {
                    post.setWorkPost(workPostRepository.findByName("店长助理"));
                    break;
                }
                case "机电主管（赋能门店）": {
                    post.setWorkPost(workPostRepository.findByName("机电主管"));
                    break;
                }
                case "美容主管（赋能门店）": {
                    post.setWorkPost(workPostRepository.findByName("美容主管"));
                    break;
                }
                case "服务顾问（赋能门店）": {
                    post.setWorkPost(workPostRepository.findByName("服务顾问"));
                    break;
                }
                case "美容技师（赋能门店）": {
                    post.setWorkPost(workPostRepository.findByName("美容组"));
                    break;
                }
                case "机电技师（赋能门店）": {
                    post.setWorkPost(workPostRepository.findByName("机电组"));
                    break;
                }

            }
            post.setLocalPermit(localPermit);
            post.setRoles(roles);
            postRepository.saveAndFlush(post);
        });

    }

    public LocalPermit setPermitPurpose(LocalPermit localPermit, BranchEntry branchEntry) {
        JSONObject permitPurposeBelong = new JSONObject();//所属权限

        JSONObject B_map = new JSONObject();
        B_map.put("id", branchEntry.getDeptId());
        B_map.put("name", branchEntry.getName());

        permitPurposeBelong.put("pt_dept", B_map);

        JSONObject B_map2 = new JSONObject();
        B_map2.put("id", branchEntry.getCompany().getId());
        B_map2.put("name", branchEntry.getCompany().getName());

        permitPurposeBelong.put("pt_company", B_map2);

        localPermit.setPermitPurposeBelong(permitPurposeBelong);
        JSONObject permitPurposeSearch = new JSONObject();// 查询权限
        JSONArray searchArray = new JSONArray();
        JSONObject searchMap = new JSONObject();
        searchMap.put("id", branchEntry.getDeptId());
        searchMap.put("name", branchEntry.getName());
        searchArray.add(searchMap);
        permitPurposeSearch.put("pt_dept", searchArray);
        JSONArray searchArray2 = new JSONArray();
        JSONObject searchMap2 = new JSONObject();
        searchMap2.put("id", branchEntry.getCompany().getId());
        searchMap2.put("name", branchEntry.getCompany().getName());
        searchArray2.add(searchMap2);
        permitPurposeSearch.put("pt_company", searchArray2);
        JSONArray searchArray3 = new JSONArray();
        permitPurposeSearch.put("pt_location", searchArray3); // 查询权限 仓库为空
        localPermit.setPermitPurposeSearch(permitPurposeSearch);

        JSONObject permitPurposeOperate = new JSONObject(); // 操作权限
        JSONArray operateArray = new JSONArray();
        JSONObject operateMap = new JSONObject();
        operateMap.put("id", branchEntry.getDeptId());
        operateMap.put("name", branchEntry.getName());
        operateArray.add(operateMap);
        permitPurposeOperate.put("pt_dept", operateArray);
        JSONArray operateArray2 = new JSONArray();
        JSONObject operateMap2 = new JSONObject();
        operateMap2.put("id", branchEntry.getCompany().getId());
        operateMap2.put("name", branchEntry.getCompany().getName());
        operateArray2.add(operateMap2);
        permitPurposeOperate.put("pt_company", operateArray2);
        JSONArray operateArray3 = new JSONArray();

        branchEntry.getLocations().forEach(location -> {
            JSONObject operateMap3 = new JSONObject();
            String id = location.getId();
            String name = location.getName();
            operateMap3.put("id", id);
            operateMap3.put("name", name);
            operateArray3.add(operateMap3);
        });
        permitPurposeOperate.put("pt_location", operateArray3);

        localPermit.setPermitPurposeOperate(permitPurposeOperate);
        return localPermit;
    }

}
